package com.tiandang.service;

import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import com.lly835.bestpay.utils.JsonUtil;
import com.tiandang.utils.MathUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tiandang.core.error.BusinessException;
import tiandang.core.error.EmBusinessError;
import tiandang.core.model.OrderInfo;
import tiandang.core.model.OrderProduct;
import tiandang.core.model.Product;
import tiandang.core.service.ManagerService;
import tiandang.core.service.OrderService;
import tiandang.core.service.ProductService;
import tiandang.core.service.PromoService;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class PayService {

  private final Logger log = LoggerFactory.getLogger(this.getClass());

  @Autowired
  private BestPayServiceImpl bestPayService;

  @Autowired
  private OrderService orderService;

  @Autowired
  private ProductService productService;

  @Autowired
  private ManagerService managerService;

  @Autowired
  private PromoService promoService;

  public PayResponse create(OrderInfo order) {
    PayRequest payRequest = new PayRequest();
    payRequest.setOpenid(order.getOpenid());
    payRequest.setOrderAmount(order.getOrderAmount().doubleValue());
    payRequest.setOrderId(order.getId());
    payRequest.setOrderName("甜档超市");
    payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
    log.info("【微信支付】发起支付, request={}", JsonUtil.toJson(payRequest));

    PayResponse payResponse = bestPayService.pay(payRequest);
    log.info("【微信支付】发起支付, response={}", JsonUtil.toJson(payResponse));
    return payResponse;
  }

  public void notify(String notifyData) throws BusinessException {
    // 1. 验证签名
    // 2. 支付的状态
    // 3. 支付金额
    // 4. 支付人(下单人 == 支付人)

    PayResponse payResponse = bestPayService.asyncNotify(notifyData);
    log.info("【微信支付】异步通知, payResponse={}", JsonUtil.toJson(payResponse));

    // 查询订单
    OrderInfo order = orderService.getOrderById(payResponse.getOrderId());

    // 判断订单是否存在
    if (order == null) {
      log.error("【微信支付】异步通知, 订单不存在, orderId={}", payResponse.getOrderId());
      throw new BusinessException(EmBusinessError.ORDER_NOT_EXIST);
    }

    // 判断金额是否一致(0.10 0.1)
    if (!MathUtil.equals(payResponse.getOrderAmount(), order.getOrderAmount().doubleValue())) {
      log.error("【微信支付】异步通知, 订单金额不一致, orderId={}, 微信通知金额={}, 系统金额={}", payResponse.getOrderId(),
        payResponse.getOrderAmount(), order.getOrderAmount());
      throw new BusinessException(EmBusinessError.WXPAY_NOTIFY_MONEY_VERIFY_ERROR);
    }

    //获取订单的状态,如果是未支付,才修改支付状态,并进行后续操作
    if(order.getPayStatus() == 0){
      //修改订单支付状态
      orderService.updatePayStatusByOrderId(payResponse.getOrderId());

      //增加对应团长的冻结佣金和未结算佣金,同时增加开团总收入
      addRewardMoney(order);
    }

  }

  //增加对应团长的冻结佣金,同时增加开团总收入
  @Transactional
  private void addRewardMoney(OrderInfo order) {
    //拿到managerId,同时拿到orderProduct列表
    List<OrderProduct> orderProductList = orderService.getOrderProductListByOrderId(order.getId());
    List<Integer> productIdList = new ArrayList<>();
    for (OrderProduct orderProduct : orderProductList) {
      productIdList.add(orderProduct.getProductId());
    }

    List<Product> productList = productService.getListByProductIdList(productIdList);
    BigDecimal rewardTotal = new BigDecimal(0);
    for (OrderProduct orderProduct : orderProductList) {
      for (Product product : productList) {
        if (orderProduct.getProductId().intValue() == product.getId().intValue()) {
          //佣金 = 商品单价x团长佣金百分比x商品数量
          BigDecimal proportion = new BigDecimal(product.getProportion()).divide(new BigDecimal(100));
          rewardTotal = rewardTotal.add(product.getPresentPrice().multiply(proportion)
            .multiply(new BigDecimal(orderProduct.getProductNumber())));
        }
      }
    }

    //增加对应团长的冻结佣金
    managerService.addFrozenReward(order.getManagerId(), rewardTotal);

    //增加开团总收入
    promoService.addIncomeAmount(order.getPromoId(),order.getOrderAmount());
  }

}
